//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#include "uCalcOO.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
// CLASSE COOColumn
//---------------------------------------------------------------------------
__fastcall COOColumn::COOColumn( CCalc *pOpenOffice, Variant vColumn) : CCalcColumn()
{
  m_pCalc   = pOpenOffice;
  m_vOleObj = vColumn;
}
//---------------------------------------------------------------------------
int __fastcall COOColumn::GetWidth()
{
  if(( bool)m_vOleObj.OlePropertyGet( "isVisible")==false) return 0;
  return ( m_vOleObj.OlePropertyGet( "Width") / 200);
}
//---------------------------------------------------------------------------
void __fastcall COOColumn::SetWidth( int nWidth)
{
  m_vOleObj.OlePropertySet( "isVisible", ( nWidth>0));
  if( nWidth>0) m_vOleObj.OlePropertySet( "Width", nWidth * 200);
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// CLASSE COOColumns
//---------------------------------------------------------------------------
__fastcall COOColumns::COOColumns( CCalc *pOpenOffice, Variant vColumns) : CCalcColumns()
{
  m_pCalc   = pOpenOffice;
  m_Column  = NULL;
  m_vOleObj = vColumns;
}
//---------------------------------------------------------------------------
__fastcall COOColumns::~COOColumns()
{
  delete m_Column;
}
//---------------------------------------------------------------------------
int __fastcall COOColumns::GetCount()
{
  return m_vOleObj.OleFunction( "getCount");
}
//---------------------------------------------------------------------------
CCalcColumn *__fastcall COOColumns::GetItem( int c)
{
  delete m_Column;

  m_Column = new COOColumn( m_pCalc, m_vOleObj.OleFunction( "getCellByPosition", c, 0).OleFunction( "getColumns"));
  return m_Column;
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// CLASSE COOStyle
//---------------------------------------------------------------------------
__fastcall COOStyle::COOStyle( CCalc *pOpenOffice) : CCalcStyle()
{
  m_pCalc = pOpenOffice;
}
//---------------------------------------------------------------------------
long __fastcall OO2RGB( long l)
{
  long r = ( l & 0x000000FF);
  long g = ( l & 0x0000FF00) >> 8;
  long b = ( l & 0x00FF0000) >> 16;

  return ( r << 16) | ( g << 8) | b;
}
//---------------------------------------------------------------------------
long __fastcall COOStyle::GetBackgroundColor()
{
  if(( bool)m_vOleObj.OlePropertyGet( "IsCellBackgroundTransparent")) return COLOR_TRANSPARENT;
  return OO2RGB( m_vOleObj.OlePropertyGet( "CellBackColor"));
}
//---------------------------------------------------------------------------
long __fastcall RGB2OO( long l)
{
  long b = ( l & 0x000000FF);
  long g = ( l & 0x0000FF00) >> 8;
  long r = ( l & 0x00FF0000) >> 16;

  return ( b << 16) | ( g << 8) | r;
}
//---------------------------------------------------------------------------
void __fastcall COOStyle::SetBackgroundColor( long lColor)
{
  if(  lColor!=COLOR_TRANSPARENT)
       m_vOleObj.OlePropertySet( "CellBackColor", RGB2OO( lColor));
  else m_vOleObj.OlePropertySet( "IsCellBackgroundTransparent", True);
}
//---------------------------------------------------------------------------
void __fastcall get_border( Variant obj, CBorder &border, const AnsiString &edge)
{
  if(( bool)obj.OlePropertyGet( AnsiString( "is") + edge + "Valid")) {
    Variant vBorder = obj.OlePropertyGet( edge);
    int     nWidth  = vBorder.OlePropertyGet( "outerLineWidth");
    border.eWeight  = nWidth<=20 ? lw_thin : lw_thick;
    border.eStyle   = ls_continuous;
  } else
    border.eStyle = ls_none;
}
//---------------------------------------------------------------------------
CBorders __fastcall COOStyle::GetBorders()
{
  CBorders eBorders;

  Variant vTableBorder = m_vOleObj.OlePropertyGet( "TableBorder");

  get_border( vTableBorder, eBorders.top              , "TopLine"       );
  get_border( vTableBorder, eBorders.right            , "RightLine"     );
  get_border( vTableBorder, eBorders.bottom           , "BottomLine"    );
  get_border( vTableBorder, eBorders.left             , "LeftLine"      );
  get_border( vTableBorder, eBorders.inside_vertical  , "VerticalLine"  );
  get_border( vTableBorder, eBorders.inside_horizontal, "HorizontalLine");

  return eBorders;
}
//---------------------------------------------------------------------------
void __fastcall set_border( Variant oo, Variant obj, CBorder border, const AnsiString &edge)
{
  Variant vBorderLine = oo.OleFunction( "Bridge_GetStruct", "com.sun.star.table.BorderLine");
          vBorderLine.OlePropertySet( "color",  RGB2OO( 0));
          vBorderLine.OlePropertySet( "lineDistance"  , 0);
          vBorderLine.OlePropertySet( "innerLineWidth", 0);
          vBorderLine.OlePropertySet( "outerLineWidth", ( border.eWeight==lw_thin ? 20 : 60));


  obj.OlePropertySet( edge, vBorderLine);
  obj.OlePropertySet( AnsiString( "is") + edge + "Valid", ( border.eStyle!=ls_none));
}
//---------------------------------------------------------------------------
void __fastcall COOStyle::SetBorders( const CBorders &eBorders)
{
  Variant vTableBorder = m_pCalc->OLEObject.OleFunction( "Bridge_GetStruct", "com.sun.star.table.TableBorder");

  set_border( m_pCalc->OLEObject, vTableBorder, eBorders.top              , "TopLine"       );
  set_border( m_pCalc->OLEObject, vTableBorder, eBorders.right            , "RightLine"     );
  set_border( m_pCalc->OLEObject, vTableBorder, eBorders.bottom           , "BottomLine"    );
  set_border( m_pCalc->OLEObject, vTableBorder, eBorders.left             , "LeftLine"      );
  set_border( m_pCalc->OLEObject, vTableBorder, eBorders.inside_vertical  , "VerticalLine"  );
  set_border( m_pCalc->OLEObject, vTableBorder, eBorders.inside_horizontal, "HorizontalLine");

  m_vOleObj.OlePropertySet( "TableBorder", vTableBorder);
}
//---------------------------------------------------------------------------
text_align __fastcall OO2Common_Align( int nAlign, bool bHorizontal)
{
  switch( nAlign) {
    case 2  : return ta_center;
    case 3  : return bHorizontal ? ta_right : ta_bottom;
    default : return bHorizontal ? ta_left : ta_top;
  }
}
//---------------------------------------------------------------------------
CTextAlign __fastcall COOStyle::GetTextAlign()
{
  CTextAlign eAlign;

  eAlign.eHorizontal = OO2Common_Align( m_vOleObj.OlePropertyGet( "HoriJustify"), true );
  eAlign.eVertical   = OO2Common_Align( m_vOleObj.OlePropertyGet( "VertJustify"), false);
  return eAlign;
}
//---------------------------------------------------------------------------
int __fastcall Common2OO_Align( text_align ta)
{
  switch( ta) {
    case ta_center : return 2;
    case ta_top    : return 1;
    case ta_right  : return 3;
    case ta_bottom : return 3;
    default        : return 1;
  }
}
//---------------------------------------------------------------------------
void __fastcall COOStyle::SetTextAlign( const CTextAlign &eAlign)
{
  m_vOleObj.OlePropertySet( "HoriJustify", Common2OO_Align( eAlign.eHorizontal));
  m_vOleObj.OlePropertySet( "VertJustify", Common2OO_Align( eAlign.eVertical  ));
}
//---------------------------------------------------------------------------
TFontStyles __fastcall COOStyle::GetFontStyle()
{
  TFontStyles eStyle;

  if( m_vOleObj.OlePropertyGet( "CharWeight" )==100) eStyle = eStyle << fsBold;
  if( m_vOleObj.OlePropertyGet( "CharPosture")==  2) eStyle = eStyle << fsItalic;
  return eStyle;
}
//---------------------------------------------------------------------------
void __fastcall COOStyle::SetFontStyle( const TFontStyles &eStyle)
{
  m_vOleObj.OlePropertySet( "CharWeight" , eStyle.Contains( fsBold  ) ? 150 : 100);
  m_vOleObj.OlePropertySet( "CharPosture", eStyle.Contains( fsItalic) ?   2 :   0);
}
//---------------------------------------------------------------------------
bool __fastcall COOStyle::GetLocked()
{
  Variant vCellProtection = m_vOleObj.OlePropertyGet( "CellProtection");
  return ( bool) vCellProtection.OlePropertyGet( "isLocked");
}
//---------------------------------------------------------------------------
void __fastcall COOStyle::SetLocked( bool bLocked)
{
  Variant vCellProtection = m_vOleObj.OlePropertyGet( "CellProtection");
          vCellProtection.OlePropertySet( "isLocked", bLocked);
  m_vOleObj.OlePropertySet( "CellProtection", vCellProtection);
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// CLASSE COOCell
//---------------------------------------------------------------------------
__fastcall COOCell::COOCell( CCalc *pOpenOffice, Variant vCell) : CCalcCell(), COOStyle( pOpenOffice)
{
  m_pCalc   = pOpenOffice;
  m_vOleObj = vCell;
}
//---------------------------------------------------------------------------
AnsiString __fastcall COOCell::GetText()
{
  return m_vOleObj.OleFunction( "getString");
}
//---------------------------------------------------------------------------
void __fastcall COOCell::SetText( const AnsiString &strText)
{
  m_vOleObj.OleProcedure( "setString", strText);
  m_vOleObj.OlePropertySet( "numberFormat", 100);
}
//---------------------------------------------------------------------------
Currency __fastcall COOCell::GetMoney()
{
  return m_vOleObj.OleFunction( "getValue");
}
//---------------------------------------------------------------------------
void __fastcall COOCell::SetMoney( const Currency &curValue)
{
  m_vOleObj.OleProcedure( "setValue", curValue);
  m_vOleObj.OlePropertySet( "numberFormat", 106);
}
//---------------------------------------------------------------------------
TDateTime __fastcall COOCell::GetDate()
{
  return m_vOleObj.OleFunction( "getString");
}
//---------------------------------------------------------------------------
void __fastcall COOCell::SetDate( const TDateTime &dtValue)
{
  m_vOleObj.OleProcedure( "setString", dtValue);
  m_vOleObj.OlePropertySet( "numberFormat", 36);
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// CLASSE COOCells
//---------------------------------------------------------------------------
__fastcall COOCells::COOCells( CCalc *pOpenOffice, Variant vCells) : CCalcCells()
{
  m_pCalc   = pOpenOffice;
  m_Cell    = NULL;
  m_vOleObj = vCells;
}
//---------------------------------------------------------------------------
__fastcall COOCells::~COOCells()
{
  delete m_Cell;
}
//---------------------------------------------------------------------------
CCalcCell *__fastcall COOCells::GetItem( int x, int y)
{
  if( m_Cell) delete m_Cell;

  m_Cell = new COOCell( m_pCalc, m_vOleObj.OleFunction( "getCellByPosition", x, y));
  return m_Cell;
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// CLASSE COORange
//---------------------------------------------------------------------------
__fastcall COORange::COORange( CCalc *pOpenOffice, Variant vRange) : CCalcRange(), COOStyle( pOpenOffice)
{
  m_pCalc   = pOpenOffice;
  m_vOleObj = vRange;
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// CLASSE COOWorksheet
//---------------------------------------------------------------------------
__fastcall COOWorksheet::COOWorksheet( CCalc *pOpenOffice, Variant vWorksheet)
{
  m_pCalc   = pOpenOffice;
  m_Cells   = NULL;
  m_Range   = NULL;
  m_Columns = NULL;
  m_vOleObj = vWorksheet;
}
//---------------------------------------------------------------------------
__fastcall COOWorksheet::~COOWorksheet()
{
  delete m_Columns;
  delete m_Range;
  delete m_Cells;
}
//---------------------------------------------------------------------------
CCalcCells *__fastcall COOWorksheet::GetCells()
{
  if( !m_Cells) m_Cells = new COOCells( m_pCalc, m_vOleObj);
  return m_Cells;
}
//---------------------------------------------------------------------------
CCalcColumns *__fastcall COOWorksheet::GetColumns()
{
  if( !m_Columns) m_Columns = new COOColumns( m_pCalc, m_vOleObj);
  return m_Columns;
}
//---------------------------------------------------------------------------
CCalcRange* __fastcall COOWorksheet::GetRange( int x1, int y1, int x2, int y2)
{
  if( m_Range) delete m_Range;

  m_Range = new COORange( m_pCalc, m_vOleObj.OleFunction( "getCellRangeByPosition", x1, y1, x2, y2));
  return m_Range;
}
//---------------------------------------------------------------------------
void __fastcall COOWorksheet::Protect( const AnsiString &strPassword)
{
  m_vOleObj.OleProcedure( "protect", strPassword);
}
//---------------------------------------------------------------------------
AnsiString __fastcall COOWorksheet::GetName()
{
  return m_vOleObj.OleFunction( "getName");
}
//---------------------------------------------------------------------------
void __fastcall COOWorksheet::SetName( const AnsiString &strName)
{
  m_vOleObj.OleProcedure( "setName", StringReplace( strName, "'", "_", TReplaceFlags() << rfReplaceAll));
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// CLASSE COOWorksheets
//---------------------------------------------------------------------------
__fastcall COOWorksheets::COOWorksheets( CCalc *pOpenOffice, Variant vWorksheets) : CCalcWorksheets()
{
  m_pCalc     = pOpenOffice;
  m_Worksheet = NULL;
  m_vOleObj   = vWorksheets;
}
//---------------------------------------------------------------------------
__fastcall COOWorksheets::~COOWorksheets()
{
  delete m_Worksheet;
}
//---------------------------------------------------------------------------
CCalcWorksheet *__fastcall COOWorksheets::GetItem( int nIndex)
{
  if( m_Worksheet) delete m_Worksheet;

  m_Worksheet = new COOWorksheet( m_pCalc, m_vOleObj.OleFunction( "getByIndex", nIndex));
  return m_Worksheet;
}
//---------------------------------------------------------------------------
int __fastcall COOWorksheets::GetCount()
{
  return m_vOleObj.OleFunction( "getCount");
}
//---------------------------------------------------------------------------
void __fastcall COOWorksheets::Add()
{
  int nCount = Count;
  m_vOleObj.OleProcedure( "insertNewByName", "Feuille" + IntToStr( nCount+1), nCount);
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// CLASSE COOWorkbook
//---------------------------------------------------------------------------
__fastcall COOWorkbook::COOWorkbook( CCalc *pOpenOffice) : CCalcWorkbook()
{
  m_pCalc      = pOpenOffice;
  m_Worksheets = NULL;
}
//---------------------------------------------------------------------------
__fastcall COOWorkbook::~COOWorkbook()
{
  delete m_Worksheets;

  if( !m_vOleObj.IsEmpty())
       m_vOleObj.OleFunction( "Close", true);
}
//---------------------------------------------------------------------------
void __fastcall COOWorkbook::Create()
{
  Variant VariantArray( OPENARRAY( int, (0, -1)), varInteger);
  int nBounds[2] = { 0, 0 };
  Variant vPropertyValue = m_pCalc->OLEObject.OleFunction( "Bridge_GetStruct", "com.sun.star.beans.PropertyValue");
  vPropertyValue.OlePropertySet( "Name", "Hidden");
  vPropertyValue.OlePropertySet( "Value", !m_pCalc->Visible);
  VariantArray = VarArrayCreate( nBounds, 1, varVariant);
  VariantArray.PutElement( vPropertyValue, 0);

  m_vOleObj = m_pCalc->OLEObject.OleFunction( "LoadComponentFromURL", "private:factory/scalc", "_blank", 0, VariantArray);
  SetVisible( m_pCalc->Visible);
}
//---------------------------------------------------------------------------
AnsiString __fastcall Convert2Url( const AnsiString &strFilename)
{
  return "file:///" + StringReplace( strFilename, "\\", "/", TReplaceFlags() << rfReplaceAll);
}
//---------------------------------------------------------------------------
void __fastcall COOWorkbook::Open( const AnsiString &strFilename)
{
  Variant VariantArray( OPENARRAY( int, (0, -1)), varInteger);
  int nBounds[2] = { 0, 0 };
  Variant vPropertyValue = m_pCalc->OLEObject.OleFunction( "Bridge_GetStruct", "com.sun.star.beans.PropertyValue");
  vPropertyValue.OlePropertySet( "Name", "Hidden");
  vPropertyValue.OlePropertySet( "Value", !m_pCalc->Visible);
  VariantArray = VarArrayCreate( nBounds, 1, varVariant);
  VariantArray.PutElement( vPropertyValue, 0);

  m_vOleObj = m_pCalc->OLEObject.OleFunction( "LoadComponentFromURL", Convert2Url( strFilename), "_blank", 0, VariantArray);
  SetVisible( m_pCalc->Visible);
}
//---------------------------------------------------------------------------
void __fastcall COOWorkbook::SaveAs( const AnsiString &strFilename)
{
  /*Variant VariantArray( OPENARRAY( int, (0, -1)), varInteger);
  m_vOleObj.OleProcedure( "storeToURL", "file:///c:/export.sxc", VariantArray);*/

  int nBounds[2] = { 0, 0 };
  Variant vPropertyValue, VariantArray;

  vPropertyValue = m_pCalc->OLEObject.OleFunction( "Bridge_GetStruct", "com.sun.star.beans.PropertyValue");
  vPropertyValue.OlePropertySet( "Name" , "FilterName" );
  vPropertyValue.OlePropertySet( "Value", "MS Excel 97");
  VariantArray = VarArrayCreate( nBounds, 1, varVariant);
  VariantArray.PutElement( vPropertyValue, 0);

  m_vOleObj.OleProcedure( "storeToURL", Convert2Url( strFilename), VariantArray);
}
//---------------------------------------------------------------------------
CCalcWorksheets *__fastcall COOWorkbook::GetWorksheets()
{
  if( !m_Worksheets) m_Worksheets = new COOWorksheets( m_pCalc, m_vOleObj.OleFunction( "getSheets"));
  return m_Worksheets;
}
//---------------------------------------------------------------------------
void __fastcall COOWorkbook::SetVisible( bool bVisible)
{
  if( m_vOleObj.IsEmpty()) return;

  Variant vController = m_vOleObj  .OleFunction( "getCurrentController");
  Variant vFrame      = vController.OleFunction( "getFrame");
  Variant vWindow     = vFrame     .OleFunction( "getContainerWindow");

  vWindow.OleProcedure( "setVisible", bVisible);
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// CLASSE COOCalc
//---------------------------------------------------------------------------
__fastcall COOCalc::COOCalc() : CCalc()
{
  m_Workbook = NULL;
  m_bVisible = false;
}
//---------------------------------------------------------------------------
void __fastcall COOCalc::Init()
{
  Variant vOpenOffice = CreateOleObject( "com.sun.star.ServiceManager");
  m_vOleObj = vOpenOffice.OleFunction( "createInstance", "com.sun.star.frame.Desktop");

  CCalc::Init();
}
//---------------------------------------------------------------------------
void __fastcall COOCalc::Terminate()
{
  CCalc::Terminate();

  delete m_Workbook;

  m_vOleObj.OleFunction( "terminate");
}
//---------------------------------------------------------------------------
bool __fastcall COOCalc::GetVisible()
{
  return m_bVisible;
}
//---------------------------------------------------------------------------
void __fastcall COOCalc::SetVisible( bool bVisible)
{
  m_bVisible = bVisible;
  (( COOWorkbook*)Workbook)->SetVisible( m_bVisible);
}
//---------------------------------------------------------------------------
CCalcWorkbook *__fastcall COOCalc::GetWorkbook()
{
  if( !m_Workbook) m_Workbook = new COOWorkbook( this);
  return m_Workbook;
}
//---------------------------------------------------------------------------

